#include "thread.h"

namespace GXL_Engine
{

	static unsigned long WINAPI thread_proc(void* param)
	{
		Thread* pThread = (Thread *)param;
		
		while(!pThread->m_bShutDown)
		{
			Runnable* pRun = pThread->m_taskQueue.PopFront();
			if (P_VALID(pRun))
			{
				pRun->Run();
			}
			else
			{
				pThread->Suspend();
			}
		}
		
		return 0;
	}


UINT32 Thread::AddTask(Runnable* pRunnable)
{
	if(P_VALID(pRunnable))
	{
		m_taskQueue.PushBack(pRunnable);
		Resume();
		return 0;
	}
	else
	{
		return -1;
	}
}


UINT32 Thread::ShutDown()
{
	ASSERT(GetCurrentThreadId() != m_dwThreadID);
	m_bShutDown = TRUE;
	Resume();
	return 0;
}

UINT32 Thread::Suspend()
{
	ASSERT(GetCurrentThreadId() == m_dwThreadID);
	return SuspendThread(m_hThread);
}

UINT32 Thread::Resume()
{
	ASSERT(GetCurrentThreadId() != m_dwThreadID);
	return ResumeThread(m_hThread);
}

VOID Thread::Join()
{
	WaitForSingleObject(m_hThread, INFINITE);
	printf("thread end\n");
}

Thread::Thread()
{
	m_bShutDown = FALSE;
	m_dwThreadID = -1;
	m_hThread = CreateThread(NULL, 0, thread_proc, this, 0, (LPDWORD)&m_dwThreadID);
}

Thread::~Thread()
{
	CloseHandle(m_hThread);
}
}